package com.xoa.dev.jinOuWorkFlowWebService.impl;

import com.alibaba.fastjson.JSONArray;
import com.xoa.dao.WFE.WFEFlowTypeModelMapper;
import com.xoa.dao.WFE.WFEFormTypeMapper;
import com.xoa.dao.users.UsersMapper;
import com.xoa.dao.work.WorkMapper;
import com.xoa.dao.workflow.FlowRunAttachMapper;
import com.xoa.dev.jinOuWorkFlowWebService.JinOuWorkFlow;
import com.xoa.dev.jinOuWorkFlowWebService.localhost.services.DocService.DocServiceLocator;
import com.xoa.dev.jinOuWorkFlowWebService.localhost.services.DocService.DocServicePortType;
import com.xoa.dev.jinOuWorkFlowWebService.util.GdPara;
import com.xoa.dev.jinOuWorkFlowWebService.util.LoadConfig;
import com.xoa.dev.jinOuWorkFlowWebService.weaver.docs.webservices.DocAttachment;
import com.xoa.dev.jinOuWorkFlowWebService.weaver.docs.webservices.DocInfo;
import com.xoa.model.enclosure.Attachment;
import com.xoa.model.users.Users;
import com.xoa.model.workflow.*;
import com.xoa.service.WFE.WFEFactory.WFEFlowProcess;
import com.xoa.service.WFE.WFELog.WFELog;
import com.xoa.service.WFE.WFERunner.WFEFlowRun;
import com.xoa.service.WFE.WFERunner.WFERunner;
import com.xoa.service.enclosure.EnclosureService;
import com.xoa.service.sys.SysTasksService;
import com.xoa.util.DateFormat;
import com.xoa.util.FileUploadUtil;
import com.xoa.util.HtmlUtil;
import com.xoa.util.ToJson;
import com.xoa.util.common.L;
import com.xoa.util.common.StringUtils;
import org.apache.axis.encoding.Base64;
import org.apache.http.entity.ContentType;
import org.jsoup.nodes.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.xml.rpc.ServiceException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;

@Service
public class JinOuWorkFlowImpl implements JinOuWorkFlow {


    private static List<Map<String, Object>> data;

    private static List<Map<String, Object>> feedBackData;

    @Autowired
    private WFERunner wfeRunner;
    @Autowired
    private EnclosureService enclosureService;
    @Autowired
    private WFEFlowRun wfeFlowRun;
    @Autowired
    private WFELog wfeLog;
    @Autowired
    private FlowRunAttachMapper flowRunAttachMapper;
    @Autowired
    private WFEFormTypeMapper wfeFormTypeMapper;
    @Autowired
    private WorkMapper workMapper;
    @Autowired
    private WFEFlowTypeModelMapper wfeFlowTypeModelMapper;
    @Autowired
    SysTasksService sysTasksService;
    @Autowired
    protected WFEFlowProcess wfeFlowProcess;
    @Autowired
    private UsersMapper usersMapper;


    @Override
    public String createWorkFlow(String strJson,String remark) {
        if(StringUtils.checkNull(strJson)){
            return "FALSE";
        }
        LoadConfig.initConfig();

        try {
            strJson = "["+strJson+"]";
            data = JSONArray.parseObject(strJson, List.class);


            String userId = wfeFlowProcess.findbyprcsId(244, 1).getPrcsUser();
            Users user = usersMapper.getUsersByuserId(userId.split(",")[0]);
            ToJson<FlowFast> workFast = wfeRunner.getWfeFlowRunInfo().workFastAdd(user, 244, 1, "1", "", null, "xoa1001", "", "0");
            FlowFast flowFast = (FlowFast) workFast.getObject();
            FlowRun flowRun = flowFast.getFlowRun();

            FlowRunPrcs flowRunPrcs = flowFast.getFlowRunPrcs();

            //StringBuffer uploadStr = new StringBuffer();
            //如果存在附件和正文
//            for (Map<String, Object> datum : data) {
//                //附件
//                if(!StringUtils.checkNull(datum.get("fj")+"")){
//                    String[] fjs = datum.get("fj").toString().split(",");
//                    for (int i = 0; i < fjs.length; i++) {
//                        uploadStr.append(upload(Integer.valueOf(fjs[i])));
//                    }
//                    datum.put("fj",uploadStr.toString());
//                }
//                //正文
//                if(!StringUtils.checkNull(datum.get("zw")+"")){
//                    String[] zws = datum.get("zw").toString().split(",");
//                    for (int i = 0; i < zws.length; i++) {
//                        putFile("xoa1001",flowRun.getRunId(),Integer.valueOf(flowRunPrcs.getFlowPrcs()),Integer.valueOf(zws[i]));
//                    }
//                }
//            }

            //2019-12-26修改为正文和附件存到收文表单上并且上传到公共附件
            StringBuffer fjAtt = new StringBuffer();
            StringBuffer zwAtt = new StringBuffer();
            data.forEach(map -> {
                try {
                    //存在附件
                    if (!StringUtils.checkNull(map.get("fj") + "")) {
                        String[] fjs = map.get("fj").toString().split(",");
                        for (int i = 0; i < fjs.length; i++) {
                            fjAtt.append(upload(Integer.valueOf(fjs[i])));
                            if(flowRunPrcs.getFlowPrcs()!=null)
                                putFile("xoa1001", flowRun.getRunId(), Integer.valueOf(flowRunPrcs.getFlowPrcs()), Integer.valueOf(fjs[i]));
                        }
                        map.put("fj",fjAtt.toString());
                    }
                    //存在正文
                    if (!StringUtils.checkNull(map.get("zw") + "")) {
                        String[] zws = map.get("zw").toString().split(",");
                        for (int i = 0; i < zws.length; i++) {
                            zwAtt.append(upload(Integer.valueOf(zws[i])));
                            if(flowRunPrcs.getFlowPrcs()!=null)
                                putFile("xoa1001", flowRun.getRunId(), Integer.valueOf(flowRunPrcs.getFlowPrcs()), Integer.valueOf(zws[i]));
                        }
                        map.put("zw",zwAtt.toString());
                    }
                }catch (Exception ex){
                    ex.printStackTrace();
                    throw new RuntimeException(ex);
                }
            });


            //保存表单数据
            saveFlowAutoNum(flowRun.getFlowId(),flowRun.getRunId(),flowRun.getRunName(),flowRun.getBeginTime(),0);

//            //给自己加上事务提醒
//            workService.todoWorkSmsBoby(masterUser, fpArray[i], tableName, runId.toString(), runName, flowId.toString(),
//                    String.valueOf(fl.getPrcsId()-1), currentPrcsId.toString(), tabId, topDefaultArray[i], smsContent, request, smsType, users, orgadd, stringBuffer.toString(), viewUser);


//            //转交下一步
//            //取下一步骤
//            String prcsTo = "";
//            List<FlowProcess> listFp = flowFast.getListFp();
//            for (FlowProcess flowProcess : listFp) {
//                if(flowRunPrcs.getPrcsId().equals(flowProcess.getPrcsId())){
//                    prcsTo = flowProcess.getPrcsTo();
//                }
//            }
//
//            //取下一步骤主办人
//            Map<Integer, Map<String, Object>> reMap = (Map<Integer, Map<String, Object>>)wfeRunner.getWfeFlowRunInfo().getBranch(flowRun.getFlowId(), Integer.valueOf(flowRunPrcs.getFlowPrcs()), flowRun.getRunId(), user).getObj();
//            List<Users> usersList= (List<Users>)reMap.get(Integer.parseInt(prcsTo.substring(0,1))).get("autoTypelist");
//            String userId = usersList.get(0).getUserId();
//
//
//            /**
//             转交下一步
//             topDefault：会签模式：0 主办人，1 先接收者主办，2 无主办人会签
//             tabId tableName 是公文会用到的，如果不用传空，先暂时传空
//             smsContent 给传阅人发的信息
//             viewUser 传阅人
//             smsType 事务提醒种类  例如：下一步骤 发起人  全部经办人
//             orgadd  新功能，暂时不用
//             beginUser 主办人
//             jianbanUser 经办人
//             flowPrcs  当前步骤
//             */
//            ToJson<FlowRunPrcs> savework = wfeRunner.getWfeFlowRunInfo().savework(flowRun.getRunId(), flowRun.getRunName(), flowRunPrcs.getPrcsId(),
//                    prcsTo, flowRun.getBeginTime(), userId, userId+",", "", user, flowRunPrcs.getPrcsId(), "0,",
//                    "", "", "", "1,", "");
//            //System.out.println(savework.getMsg());
            return "TRUE";
        }catch (Exception e){
            e.printStackTrace();
            L.e("gd===="+e);
        }
        return "FALSE";
    }





    //保存表单数据
    public void saveFlowAutoNum(Integer flowId, Integer
            runId, String runName,String beginTime,int flag) throws Exception{

        String sqlType = "xoa1001";

        String tableName = "flow_data_" + flowId;
        //获取该表数据库中的所有的列
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("tableName", tableName);
        param.put("tableSchema", sqlType);

        //根据flowId获取表单信息，然后获取表单上所有name属性生成flow_data_flowid表
        List<FlowFormType> forms = wfeFormTypeMapper.getFrombyFlowId(flowId);
        FlowFormType formType = forms.get(0);
        //获取表单信息
        Document document = HtmlUtil.getDom(formType.getPrintModel());
        List<String> list = HtmlUtil.getAllData(document);

        //获取该表所有的列
        List<String> columns = workMapper.showColumns(param);
        //没有表则新建
        if (columns.size() == 0) {

            param.put("keys", list);
            //读取配置文件
            ResourceBundle rb = ResourceBundle.getBundle("jdbc-sql");
            String databaseId = rb.getString("driverClassName");
            if (databaseId.contains("oracle")) {
                workMapper.createSequence(param);
            }
            workMapper.createTable(param);
        }
        Integer flowAutoNum = null;
        //查询该表单的信息
        param.put("runId",runId);
        Map<String, Object> m = workMapper.select(param);
        if (m == null || m.size() == 0) {
            List<String> key = new ArrayList<String>();
            List<String> value = new ArrayList<String>();
            key.add("RUN_ID");
            value.add(String.valueOf(runId));
            key.add("RUN_NAME");
            value.add(runName);
            key.add("BEGIN_TIME");
            value.add(beginTime);
            key.add("BEGIN_USER");
            value.add("admin");

            FlowTypeModel flowTypeModel = wfeFlowTypeModelMapper.queryOneObject(flowId);
            if (flowTypeModel.getAutoNum() != null && flowTypeModel.getAutoNum() != 0) {
                flowAutoNum = flowTypeModel.getAutoNum() + 1;
                key.add("FLOW_AUTO_NUM");
                value.add(flowAutoNum.toString());
            }

//                for (String temp : list) {
//                    key.add(temp);
//                    value.add(getVal(temp));
//                }
            getVal(key,value,list);
            //针对表单删除（数据库没删除）的字段处理
            //移除数据库中非DATA开头的数据
            Iterator<String> it = columns.iterator();
            while (it.hasNext()) {
                String x = it.next();
                if (!x.toUpperCase().contains("DATA")) {
                    it.remove();
                }
            }

            List<String> copyKey = new ArrayList<String>();
            copyKey.addAll(key);
            Iterator<String> copyIt = copyKey.iterator();
            while (copyIt.hasNext()) {
                String x = copyIt.next();
                if (!x.toUpperCase().contains("DATA")) {
                    copyIt.remove();
                }
            }
            columns.removeAll(copyKey);
            for (String s : columns) {
                key.add(s);
                value.add("");
            }
//            boolean f = false;
//            for (String column : columns) {
//                for (String ck : copyKey) {
//                    if(ck.toUpperCase().contains("DATA") && column.equals(ck)){
//                        f = true;
//                    }
//                }
//                if(f) {
//                    key.add(column);
//                    value.add("");
//                }
//            }
            param.put("keys", key);
            param.put("values", value);
            workMapper.insert(param);
        }
    }

    //获取默认库名
    public String getSqlType() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("tableSchema", "xoa1000");
        map.put("tableName", "user");
        List<String> list = workMapper.showColumns(map);
        String sqlType = "xoa1000";
        if (list.size() == 0) {
            sqlType = "xoa1001";
        }
        return sqlType;
    }





    //{"标题":"DATA_28",
    // "责任者":"DATA_29",
    // "责任者流水号":"DATA_30",
    // "密级":"DATA_7",
    // "文号":"DATA_31",
    // "报文日期":"DATA_32",
    // "急缓":"DATA_8",
    // "发文编号1":"DATA_33",
    // "发文编号2":"DATA_34",
    // "文件日期":"DATA_37",
    // "综合管理部意见":"DATA_11",
    // "董事长批示":"DATA_13",
    // "主送":"DATA_17",
    // "抄送":"DATA_14",
    // "承办部门意见":"DATA_18",
    // "备注":"DATA_19",
    // "领导批示":"DATA_20",
    // "批示意见":"DATA_38",
    // "领导批示签字":"DATA_39",
    // "正文":"DATA_21",
    // "附件":"DATA_36"}


    //2019-12-26表单调整后
    //{"标题":"DATA_28",
    // "来文单位":"DATA_29",
    // "来文流水号":"DATA_30",
    // "密级":"DATA_7",
    // "文号":"DATA_31",
    // "收文日期":"DATA_32",
    // "急缓":"DATA_8",
    // "综合管理部意见":"DATA_61",
    // "董事长批示":"DATA_64",
    // "主送":"DATA_42",
    // "抄送":"DATA_43",
    // "承办部门意见":"DATA_58",
    // "备注":"DATA_19",
    // "领导批示":"DATA_59",
    // "正文":"DATA_66",
    // "附件":"DATA_55"}
    public void getVal(List<String> key,List<String> value,List<String> list){
        for (String str : list) {
            key.add(str);
            for (Map<String, Object> datum : data) {

                switch (str){
                    case "DATA_28"://标题
                        value.add(datum.get("bt")+"");
                        break;
                    case "DATA_29"://责任者
                        value.add("光大集团");
                        break;
                    case "DATA_30"://责任者流水号
                        String fwbh = datum.get("fwbh").toString();
                        value.add(fwbh.substring(4));
                        break;
                    case "DATA_31"://文号
                        value.add(datum.get("fwbh")+"");
                        break;
                    case "DATA_32"://报文日期
                        value.add(DateFormat.getDatestr(new Date()));
                        break;
                    case "DATA_37"://发文日期
                        value.add(datum.get("fwrq")+"");
                        break;
                    case "DATA_55"://附件
                        //附件上传
                        value.add(datum.get("fj")+"");
                        break;
                    case "DATA_7"://密级
                        value.add(datum.get("mj")+"");
                        break;
                    case "DATA_8"://急缓
                        value.add(datum.get("jh")+"");
                        break;
                    case "DATA_66"://正文
                        value.add(datum.get("zw")+"");
                        break;
                    default:
                        value.add("");
                        break;
                }
            }
        }

    }


    //{"标题":"DATA_28","来文单位":"DATA_29","来文流水号":"DATA_30","密级":"DATA_7","文号":"DATA_31","收文日期":"DATA_32","急缓":"DATA_8","综合管理部意见":"DATA_11","董事长批示":"DATA_13","主送":"DATA_42","抄送":"DATA_43","承办部门意见":"DATA_18","备注":"DATA_19","领导批示":"DATA_20","正文":"DATA_21","附件":"DATA_55"}
    public void getVal2(List<Object> key,List<Object> value,List<String> list){
        for (String str : list) {
            key.add(str);
            for (Map<String, Object> datum : feedBackData) {

                switch (str){
                    case "DATA_18"://标题
                        value.add(datum.get("spyjs"));
                        break;
                    default:
                        value.add("");
                        break;
                }
            }
        }

    }


    public ToJson<Attachment> putFile(String company, Integer runId, Integer flowPrcs, int attId) throws IOException {
        DocServiceLocator docServiceLocator = new DocServiceLocator();
        ToJson<Attachment> json = new ToJson<Attachment>();
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            //根据Eclipse生成的Web Service客户端程序，取得接口
            DocServicePortType service = docServiceLocator.getDocServiceHttpPort(new URL(GdPara.url));
            String session = service.login(GdPara.u, GdPara.p, 0, GdPara.ip);
            System.out.println(session);
            //根据ID取得文档内容
            DocInfo docInfo = service.getDoc(attId, session);
            MultipartFile[] files = new MultipartFile[0];
            if(docInfo!=null){
                //附件
                DocAttachment[] doc = docInfo.getAttachments();
                files = new MultipartFile[doc.length];
                int len = 0;
                for (DocAttachment da : doc) {
                    //得到附件内容
                    byte[] content = Base64.decode(da.getFilecontent());
                    InputStream inputStream = new ByteArrayInputStream(content);
                    MultipartFile file = new MockMultipartFile(da.getFilename(),da.getFilename(), ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
                    files[len] = file;
                    len++;
                }
            }
            List<Attachment> list = enclosureService.upload(files, company, "workflow");
            FlowRunAttach flowRunAttach = new FlowRunAttach();
            Object[] o = FileUploadUtil.reAttachment(list);
            flowRunAttach.setRunId(runId);
            flowRunAttach.setAttachmentId(o[0].toString());
            if (flowPrcs == null) {
                flowRunAttach.setFlowPrcs(0);
            } else {
                flowRunAttach.setFlowPrcs(flowPrcs);
            }

            Date d = new Date();
            String d1 = DateFormat.getStrDate(d);
            flowRunAttach.setUploadTime(d1);
            flowRunAttach.setUploadUser("系统管理员");
            flowRunAttach.setAttachmentName(o[1].toString());

            flowRunAttachMapper.insertSelective(flowRunAttach);

            FlowRun flowRun = wfeFlowRun.find(runId);
            String attcahmentId = flowRun.getAttachmentId();
            String attachmentName = flowRun.getAttachmentName();
            StringBuffer id = new StringBuffer();
            StringBuffer name = new StringBuffer();
            if (attcahmentId != "" || attachmentName != "") {
                id.append(attcahmentId);
                name.append(attachmentName);
            }

            map.put("runId", runId);
            if (!StringUtils.checkNull(flowRun.getAttachmentId())) {
                if (!",".equals(flowRun.getAttachmentId().substring(flowRun.getAttachmentId().length() - 1, flowRun.getAttachmentId().length()))) {
                    flowRun.setAttachmentId(flowRun.getAttachmentId() + ",");
                }
            }
            if (!StringUtils.checkNull(flowRun.getAttachmentName())) {
                if (!"*".equals(flowRun.getAttachmentName().substring(flowRun.getAttachmentName().length() - 1, flowRun.getAttachmentName().length()))) {
                    flowRun.setAttachmentName(flowRun.getAttachmentName() + "*");
                }
            }

            map.put("attachmentId", flowRun.getAttachmentId() + o[0].toString());
            map.put("attachmentName", flowRun.getAttachmentName() + o[1].toString());
            wfeFlowRun.updateAttachment(map);
            json.setObj(list);
            json.setMsg("OK");
            json.setFlag(0);
//            /****   lr 工作流使用添加日志 --上传附件 ****/
//            FlowRunLog flowRunLog = wfeLog.getFlowRunLogByRequest(request);
//            flowRunLog.setType(Constant.TYPE8);
//            flowRunLog.setPrcsId(flowRunAttach.getFlowPrcs());
//            flowRunLog.setRunId(Integer.parseInt(runId));
//            flowRunLog.setAccessory(flowRun.getAttachmentName() + o[1].toString());
//            wfeLog.addFlowRunLog(flowRunLog);

        } catch (ServiceException e) {
            e.printStackTrace();
        }
        return json;
    }


    public String upload(int attId) {
        DocServiceLocator docServiceLocator = new DocServiceLocator();
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            //根据Eclipse生成的Web Service客户端程序，取得接口
            DocServicePortType service = docServiceLocator.getDocServiceHttpPort(new URL(GdPara.url));
            String session = service.login(GdPara.u, GdPara.p, 0, GdPara.ip);
            System.out.println(session);
            //根据ID取得文档内容
            DocInfo docInfo = service.getDoc(attId, session);
            if(docInfo!=null){
                //附件
                DocAttachment[] doc = docInfo.getAttachments();
                MultipartFile[] files = new MultipartFile[doc.length];
                int len = 0;
                for (DocAttachment da : doc) {
                    //得到附件内容
                    byte[] content = Base64.decode(da.getFilecontent());
                    InputStream inputStream = new ByteArrayInputStream(content);
                    MultipartFile file = new MockMultipartFile(da.getFilename(),da.getFilename(), ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
                    files[len] = file;
                    len++;
                }
                List<Attachment> list = enclosureService.upload(files, "xoa1001", "workflow");
                return list.get(0).getAttUrl()+"&userid=admin*";
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ServiceException e) {
            e.printStackTrace();
        } finally {

        }
        return "";
    }

}
